//
// Created by feng on 19-3-28.
// PS: Define the sun ray data structure.
//
#include "CudaSunRay.cuh"
#include <algorithm/rayTracing/qmcrt_util/check_cuda.h>

using namespace solar::cuda;

void CudaSunray::CClear()
{
    if (d_perturbation_ != nullptr)
    {
        checkCudaErrors(cudaFree(d_perturbation_));
        d_perturbation_ = nullptr;
    }
    if (d_samplelights_ != nullptr)
    {
        checkCudaErrors(cudaFree(d_samplelights_));
        d_samplelights_ = nullptr;
    }
    /*if(d_uniform_){
        checkCudaErrors(cudaFree(d_uniform_));
        d_uniform_ = nullptr;
    }*/
}

CudaSunray::~CudaSunray()
{
    if (d_perturbation_)
        d_perturbation_ = nullptr;
    if (d_samplelights_)
        d_samplelights_ = nullptr;
    /*if(d_uniform_)
        d_uniform_ = nullptr;*/
}

/**
 * Getters and setters of attributes for sun ray object.
 */
__device__ __host__ auto CudaSunray::getSunDirection() const -> float3 { return sun_dir_; }
void CudaSunray::setSunDirection(float3 sun_dir)
{
    // std::cout << "CudaSunray::setSunDirection" << std::endl;
    // std::cout << sun_dir_.x << std::endl;
    // std::cout << sun_dir.x << std::endl;
    sun_dir_ = sun_dir;
    // sun_dir_ = float3(1.0, 2.0, 0.0);

    // std::cout << "CudaSunray::setSunDirection end" << std::endl;
}

__device__ __host__ auto CudaSunray::getDNI() const -> float { return dni_; }
void CudaSunray::setDNI(float dni)
{
    // std::cout << "CudaSunray::setDNI" << std::endl;
    dni_ = dni;
    // std::cout << "CudaSunray::setDNI end" << std::endl;
}

__device__ __host__ auto CudaSunray::getCSR() const -> float { return csr_; }
void CudaSunray::setCSR(float csr)
{
    // std::cout << "CudaSunray::setCSR" << std::endl;
    // csr_ = csr;
    // std::cout << "CudaSunray::setCSR end" << std::endl;
}

__device__ __host__ auto CudaSunray::getNumOfSunshapeGroups() const -> int
{
    return num_sunshape_groups_;
}
void CudaSunray::setNumOfSunshapeGroups(int num_sunshape_groups)
{
    num_sunshape_groups_ = num_sunshape_groups;
}

__device__ __host__ auto CudaSunray::getNumOfSunshapeLightsPerGroup() const -> int
{
    return num_sunshape_lights_per_group_;
}
void CudaSunray::setNumOfSunshapeLightsPerGroup(int num_sunshape_lights_per_group)
{
    num_sunshape_lights_per_group_ = num_sunshape_lights_per_group;
}

__device__ __host__ auto CudaSunray::getDeviceSampleLights() const -> float3*
{
    return d_samplelights_;
}
void CudaSunray::setDeviceSampleLights(float3* d_samplelights) { d_samplelights_ = d_samplelights; }
__device__ __host__ auto CudaSunray::getDeviceTheta() const -> float* { return d_theta_; }
void CudaSunray::setDeviceTheta(float* d_theta) { d_theta_ = d_theta; }
/*float *CudaSunray::getDeviceUniform() const{
    return d_uniform_;
}
void CudaSunray::setDeviceUniform(float *d_uniform){
    d_uniform_ = d_uniform;
}*/
__device__ __host__ auto CudaSunray::getDevicePerturbation() const -> float3*
{
    return d_perturbation_;
}
void CudaSunray::setDevicePerturbation(float3* d_perturbation) { d_perturbation_ = d_perturbation; }

auto CudaSunray::getReflectiveRate() const -> float { return reflective_rate_; }
void CudaSunray::setReflectiveRate(float reflective_rate) { reflective_rate_ = reflective_rate; }
